home *** CD-ROM | disk | FTP | other *** search
- Path: ix.netcom.com!news
- From: Kugan Kandasamy <kandasam@ix.netcom.com>
- Newsgroups: comp.lang.c++
- Subject: C++ design question
- Date: Fri, 05 Apr 1996 21:35:44 -0800
- Organization: Netcom
- Message-ID: <316602B0.5DE@ix.netcom.com>
- NNTP-Posting-Host: irv-ca7-25.ix.netcom.com
- Mime-Version: 1.0
- Content-Type: text/plain; charset=us-ascii
- Content-Transfer-Encoding: 7bit
- X-NETCOM-Date: Fri Apr 05 11:37:56 PM CST 1996
- X-Mailer: Mozilla 2.0 (Win95; I)
-
- This is a C++/design question.
-
- I am attempting to create a "link" between objects by defining
- a Link class that stores a pointer to the linked object. An object can
- have as many links as possible. All classes that use Link are derived
- from class Root.
-
- The source looks as follows. It compiles and runs as expected:
-
- // ------------------------------------------------------------------------
-
- #include <iostream.h>
-
- // All classes that embed Links need to be derived from Root. See use of
- // Root* in the Link class.
-
- class Root
- {
- };
-
- // ---------------------------------------------------------------------------
-
- template <class T>
- class Link
- {
- Root *m_ptr;
- public:
- Link(): m_ptr(0) {}
- Link (Root *ptr) : m_ptr(ptr) {}
- // ~Link() { m_ptr->link.unset(); }
-
- void set(Root *ptr) { m_ptr = ptr; }
- void unset() { m_ptr = NULL; }
-
- T* operator-> () { return ((T*)m_ptr); }
- };
-
- // ---------------------------------------------------------------------------
- // The Connect function connects two objects pointed to by "a" and "b" via
- // links "alink" and "blink"
-
- template <class T1, class T2>
- void Connect (Root *a, Root *b, Link<T1> &alink, Link<T2> &blink)
- {
- alink.set(b);
- blink.set(a);
- }
-
- // ---------------------------------------------------------------------------
- // What follows is user code.
-
- class B;
-
- class A : public Root
- {
- public:
- Link<B> a2b; // Establishes a "port" on which to connect B type object.
- void print() { cout << "In A : " << "\n"; }
- };
-
- // ---------------------------------------------------------------------------
-
- class B : public Root
- {
- public:
- Link<A> b2a; // Establishes a "port" on which to connect A type object.
- void print() { cout << "In B : " << "\n"; }
- };
-
- // ---------------------------------------------------------------------------
-
- main()
- {
- A *a = new A; B *b = new B;
-
- Connect(a, b, a->a2b, b->b2a);
-
- cout << "Before deleting a\n";
- cout << "b->b2a : " << b->b2a.operator->() << endl;
-
- delete a;
-
- cout << "After deleting a\n";
- cout << "b->b2a : " << b->b2a.operator->() << endl;
-
- cout << endl;
-
- return 0;
- }
-
- ----------------------------------------------------------------------------
-
- I'd like to maintain referential integrity when objects are deleted.
- I want to avoid dangling pointers in link objects when a connection is broken.
- Since all links are two way, given the mode in which connections are established
- with the "Connect" function, I know all the other objects that connect to the
- object being deleted. I want to do something like that shown in the destructor
- of the Link class:
-
- ~Link() { m_ptr->link.unset(); }
-
- where "link" is the "port" on the other object that is used to connect
- to me. How can I achieve this? I realize that this "foreign link" information
- must have been supplied at template instantiation time. So maybe a link is
- declared as:
-
- class A : public Root
- {
- public:
- Link<B,b2a> a2b; // Note two parameters in template class.
- };
-
- I cannot, however, define my template Link class like this:
-
- template <class T, Link link>
- class Link
- {
- ....
- };
-
- Any ideas will be appreciated.
-
- Regards
- Kugan
- kandasam@ix.netcom.com
-